package com.lam.system.service.impl;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lam.common.components.easyexcel.imp.model.AbstractImportBody;
import com.lam.common.components.easyexcel.imp.model.ImportEntry;
import com.lam.common.components.easyexcel.imp.model.ImportWrapper;
import com.lam.common.components.easyexcel.imp.service.AbstractImportService;
import com.lam.common.components.parameter.ParameterConfigUtil;
import com.lam.common.constant.CommonConstant;
import com.lam.common.context.TokenUtils;
import com.lam.common.exception.BusinessException;
import com.lam.common.exception.ParameterErrorException;
import com.lam.common.utils.CollectionUtil;
import com.lam.common.utils.Md5Util;
import com.lam.common.utils.PasswordUtil;
import com.lam.common.utils.StringUtils;
import com.lam.common.utils.uuid.IdUtils;
import com.lam.system.entity.SysDeptUser;
import com.lam.system.entity.SysUser;
import com.lam.system.entity.imp.SysUserImp;
import com.lam.system.mapper.SysMenuMapper;
import com.lam.system.mapper.SysUserMapper;
import com.lam.system.mapper.SysUserRoleMapper;
import com.lam.system.param.SysDeptUserParam;
import com.lam.system.param.SysUserParam;
import com.lam.system.service.SysDeptUserService;
import com.lam.system.service.SysUserService;

/**
 * 用户Service业务层处理
 * 
 * @author admin
 * @date 2022-08-04
 */
@Service
public class SysUserServiceImpl extends AbstractImportService<SysUserImp, SysUser> implements SysUserService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysDeptUserService sysDeptUserService;
//    @Autowired
//    private SysFrontMenuMapper sysFrontMenuMapper;

	@Override
	public Set<String> loadUserRoles(String uid) {
		// 查询用户拥有的角色集合
		return new HashSet<>(sysUserRoleMapper.getRoleByUid(uid));
	}

	@Override
	public Set<String> loadUserAdmAuths(String uid) {
		List<String> list = sysMenuMapper.selectPermsByUid(uid);
		Set<String> set = new HashSet<>();
		list.stream().filter(t->StringUtils.isNotBlank(t)).forEach(t->{
			if(t.contains(",")) {
				Arrays.asList(t.split(",")).stream().map(tt->StringUtils.trim(tt)).filter(tt->StringUtils.isNotBlank(tt)).forEach(tt->set.add(tt));
			}else {
				set.add(t);
			}
		});
		return set;
	}
	
//	@Override
//	public Set<String> loadUserFrontAuths(String uid) {
//		
//		return sysFrontMenuMapper.selectPermsByUid(uid).stream().filter(t->StringUtils.isNotBlank(t)).collect(Collectors.toSet());
//	}
	
    /**
     * 查询用户
     * 
     * @param id ID
     * @return 单个对象
     */
    @Override
    @Transactional(readOnly = true)
    public SysUser selectById(String id) {

        return sysUserMapper.selectById(id);
    }
    
    @Override
    @Transactional(readOnly = true)
    public SysUser selectByIdWithDept(String id) {
    	
    	SysUser sysUser = sysUserMapper.selectById(id);
    	if(sysUser != null) {
    		SysDeptUserParam param = new SysDeptUserParam();
    		param.setUserId(id);
    		SysDeptUser dept = CollectionUtil.getFirst(sysDeptUserService.selectList(param));
    		if(dept != null) {
    			sysUser.setDeptId(dept.getDeptId());
    		}
    	}
        return sysUser;
    }
    
    /**
     * 查询用户
     * 
     * @param id ID
     * @return 单个对象
     */
    @Override
    @Transactional(readOnly = true)
    public SysUser selectByUsername(String username) {
    	
    	QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
    	queryWrapper.eq("username", username);
    	queryWrapper.last("LIMIT 1");
    	return sysUserMapper.selectOne(queryWrapper);
    }

    /**
     * 查询用户列表
     * 
     * @param param
     * @return 
     */
    @Override
    @Transactional(readOnly = true)
    public List<SysUser> selectList(SysUserParam param) {
    
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        
        //关键字查询
        if(StringUtils.isNotBlank(param.getKeywords())) {
        	queryWrapper.and(wr->{
        		wr.or().like("username", param.getKeywords());
        		wr.or().like("realname", param.getKeywords());
        		wr.or().like("phone", param.getKeywords());
        		wr.or().like("email", param.getKeywords());
        	});
        }
        
        queryWrapper.like(StringUtils.isNotBlank(param.getUsernameKey()), "username", param.getUsernameKey());
        queryWrapper.eq(StringUtils.isNotBlank(param.getUsername()), "username", param.getUsername());
        queryWrapper.eq(Objects.nonNull(param.getRegType()), "reg_type", param.getRegType());
        queryWrapper.like(StringUtils.isNotBlank(param.getRealnameKey()), "realname", param.getRealnameKey());
        queryWrapper.eq(StringUtils.isNotBlank(param.getRealname()), "realname", param.getRealname());
        queryWrapper.like(StringUtils.isNotBlank(param.getEmailKey()), "email", param.getEmailKey());
        queryWrapper.eq(StringUtils.isNotBlank(param.getEmail()), "email", param.getEmail());
        queryWrapper.like(StringUtils.isNotBlank(param.getPhoneKey()), "phone", param.getPhoneKey());
        queryWrapper.eq(StringUtils.isNotBlank(param.getPhone()), "phone", param.getPhone());
        queryWrapper.like(StringUtils.isNotBlank(param.getWorkNoKey()), "work_no", param.getWorkNoKey());
        queryWrapper.eq(StringUtils.isNotBlank(param.getWorkNo()), "work_no", param.getWorkNo());
        queryWrapper.eq(Objects.nonNull(param.getUserType()), "user_type", param.getUserType());
        queryWrapper.eq(Objects.nonNull(param.getIsNew()), "is_new", param.getIsNew());
        queryWrapper.eq(Objects.nonNull(param.getStatus()), "status", param.getStatus());

        return sysUserMapper.selectList(queryWrapper);
    }
    
    /**
     * 查询用户列表
     * 
     * @param param
     * @return 
     */
    @Override
    @Transactional(readOnly = true)
    public List<SysUser> toSelectList(SysUserParam param) {
    	
    	QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
    	switch (param.getSelectType()) {
    	//角色下的用户
		case "roleUser": 
        	queryWrapper.inSql("id", String.format("select user_id from sys_user_role where role_id='%s'", param.getRoleId()));
			break;
		//角色添加用户的候选列表
		case "roleToSelectUser": 
			queryWrapper.eq("status", CommonConstant.USER_NOMAL);
			queryWrapper.notInSql("id", String.format("select user_id from sys_user_role where role_id='%s'", param.getRoleId()));
			break;
			
		//组织机构下的用户
		case "deptUser": 
			queryWrapper.inSql("id", String.format("select user_id from sys_dept_user where dept_id='%s'", param.getDeptId()));
			break;
		//组织机构添加用户的候选列表
		case "deptToSelectUser":
			queryWrapper.eq("status", CommonConstant.USER_NOMAL);
			queryWrapper.notInSql("id", String.format("select user_id from sys_dept_user"));
			break;

		default:break;
		}
    	//关键字查询
        if(StringUtils.isNotBlank(param.getKeywords())) {
        	queryWrapper.and(wr->{
        		wr.or().like("username", param.getKeywords());
        		wr.or().like("realname", param.getKeywords());
        		wr.or().like("phone", param.getKeywords());
        		wr.or().like("email", param.getKeywords());
        	});
        }
    	
    	return sysUserMapper.selectList(queryWrapper);
    }

    /**
     * 新增用户
     * 
     * @param sysUser 
     * @return 
     */
    @Override
    @Transactional
    public int insert(SysUser sysUser) {
    	
    	if(selectByUsername(sysUser.getUsername()) != null) {
    		throw new ParameterErrorException(String.format("用户【%s】已存在", sysUser.getUsername()));
    	}
    	initUser(sysUser);
    	int n = sysUserMapper.insert(sysUser);
    	if(n > 0) {
    		SysDeptUser sysDeptUser = new SysDeptUser();
    		sysDeptUser.setDeptId(sysUser.getDeptId());
    		sysDeptUser.setUserId(sysUser.getId());
    		sysDeptUserService.insert(sysDeptUser);
    	}
        return n;
    }
    
    private void initUser(SysUser sysUser) {
    	
		sysUser.setSalt(IdUtils.genRandom(8));
		sysUser.setPassword(Md5Util.md5Encrypt(ParameterConfigUtil.getValue("init.user.pwd", "123456")));
    	sysUser.setPassword(PasswordUtil.encrypt(sysUser.getUsername(), sysUser.getPassword(), sysUser.getSalt()));
    	sysUser.setIsNew(CommonConstant.YES1);
    }

    /**
     * 修改用户
     * 
     * @param sysUser 
     * @return 
     */
    @Override
    @Transactional
    public int update(SysUser sysUser) {
    	
    	//不允许修改用户名
    	sysUser.setUsername(null);
        int n = sysUserMapper.updateById(sysUser);
        if(n > 0) {
        	sysDeptUserService.deleteByUser(sysUser.getId(), null);
        	if(StringUtils.isNotBlank(sysUser.getDeptId())) {
        		SysDeptUser sysDeptUser = new SysDeptUser();
        		sysDeptUser.setDeptId(sysUser.getDeptId());
        		sysDeptUser.setUserId(sysUser.getId());
        		sysDeptUserService.insert(sysDeptUser);
        	}
    	}
        return n;
    }

    @Override
    @Transactional
    public int updateAvatar(String id, String avatar) {
    	
    	SysUser sysUser = new SysUser();
		sysUser.setId(id);
		sysUser.setAvatar(avatar);
		sysUser.setUpdateBy(TokenUtils.getLoginUsername());
		sysUser.setUpdateTime(new Date());
        return sysUserMapper.updateById(sysUser);
    }

    @Override
    @Transactional
	public int resetPwd(SysUserParam param) {
    	
    	SysUser user = selectById(param.getId());
    	if(user == null) {
    		logger.error("重置密码时检查到该用户不存在，userId:{}", param.getId());
    		throw new BusinessException("该用户不存在！");
    	}
    	
    	SysUser sysUser = new SysUser();
		sysUser.setId(param.getId());
		sysUser.setUsername(user.getUsername());
		initUser(sysUser);
        return sysUserMapper.updateById(sysUser);
	}
    
    @Override
    @Transactional
	public int updatePwd(SysUserParam param) {
    	
    	SysUser user = selectById(TokenUtils.getLoginUserid());
    	
    	String userpassword = PasswordUtil.encrypt(user.getUsername(), param.getOldpassword(), user.getSalt());
		if (!StringUtils.equals(user.getPassword(), userpassword)) {
			throw new BusinessException("errorTip.wrongOldPwd");
		}
    	
    	SysUser sysUser = new SysUser();
    	sysUser.setId(user.getId());
    	sysUser.setPassword(PasswordUtil.encrypt(user.getUsername(), param.getPassword(), user.getSalt()));
    	
        return sysUserMapper.updateById(sysUser);
	}

    /**
     * 删除用户信息
     * 
     * @param idStr ID，多个用逗号分隔
     * @return 
     */
    @Override
    @Transactional
    public int deleteById(String idStr) {
    	if(StringUtils.isBlank(idStr)) {
            return 0;
    	}
    	
    	int n = 0;
    	for (String userId : StringUtils.str2List(idStr)) {
            n += sysUserMapper.deleteById(userId);
            sysUserRoleMapper.deleteByUserId(userId, null);
            sysDeptUserService.deleteByUser(userId, null);
        }
        return n;
    }
    
    @Override
    @Transactional
    public void importData(ImportWrapper<SysUserImp, SysUser> wrapper) {
        
    	QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
    	importData(wrapper, new AbstractImportBody<SysUserImp, SysUser>() {
			@Override
			public SysUser selectRecord(ImportEntry<SysUserImp, SysUser> entry) {
				queryWrapper.clear();
				queryWrapper.select("id").last("limit 1");
				queryWrapper.eq("username", entry.getData().getUsername());
				return sysUserMapper.selectOne(queryWrapper);
			}
			@Override
			public int insertData(SysUser data) {
				return insert(data);
			}
			@Override
			public int updateData(SysUser data) {
				return update(data);
			}
			@Override
			public String notUniqueMsg(ImportEntry<SysUserImp, SysUser> entry) {
				return MessageFormat.format("登录账号【{0}】已存在", entry.getData().getUsername());
			}
    	});
    }

}
